local _G = getfenv(0)
local objects = {}
local tcolor, stime = "|cff637eae", 0, 0, 0
local color = _G["RAID_CLASS_COLORS"][select(2, UnitClass("player"))] or { r=1, g=1, b=1, a=1 }

letter = function(value)
    if value then
       if value < 1 then
          return string.format("%.2f", value)
       elseif value >= 10000000 then 
          return string.format("%.1fm", value / 1000000) 
       elseif value >= 1000000 then
          return string.format("%.2fm", value / 1000000) 
       elseif value >= 100000 then
          return string.format("%.0fk", value / 1000) 
       elseif value >= 10000 then
          return string.format("%.1fk", value / 1000) 
       else
          return math.ceil(value)
       end
    end
end
    
rgb2str = function(col) local r, g, b = unpack(col) return format("|cff%02x%02x%02x", r*255, g*255, b*255) end
rgb2str = function(r, g, b) return format("|cff%02x%02x%02x", r*255, g*255, b*255) end

gradient_s = function(val, bad, good)
    gradient = function(val, bad, good)
        local percent, r, g
        if (good > bad) then 
            percent = val/(good-bad)
        else 
            percent = 1-val/(bad-good) 
        end
        if (percent > 1) then percent = 1 end
        if (percent < 0) then percent = 0 end
        if(percent < 0.5) then r, g = 1, 2*percent   else  r, g = (1-percent)*2, 1 end
        return r, g, 0
    end
    return rgb2str(gradient(val, bad, good))
end 
   
local line  = function(m1, m2) GameTooltip:AddDoubleLine(m1, m2, 0.5, 02, 0.7, 0.7, 0.7, 0.2) end
local space = function() GameTooltip:AddLine("\n") end

local guildname = GetGuildInfo("player")

local Holder = CreateFrame("Frame", "Holder", UIParent)

local createFs = function(parent, justify, ownfsize, fstyle)
    if SCDB["Main"]["ClassColorTheme"] == false then
        color = { r=1, g=1, b=1, a=1 }
    end
    local f = parent:CreateFontString(nil, "OVERLAY", "GameFontHighlight")
    f:SetTextColor(color.r, color.g, color.b)
    if(justify) then 
        f:SetJustifyH(justify) 
    end
    return f
end
    
function checkStats()
    for i, object in pairs(objects) do
        if (i=="gold") then
            object.text:SetText(GetMoneyString(GetMoney()))			-- GetCoinTextureString(GetMoney()))
        elseif i=="Menu" then
            object.text:SetText(format("%s%s|r", tcolor, MAINMENU_BUTTON))
        elseif i=="dura" then
            object.text:SetText(select(1, show_durability()))
            object.progress:SetValue(select(2, show_durability()) or 0)
        elseif i=="tm" then
            object.text:SetText(format("%s%s|r", tcolor, date("%H:%M")))
        elseif i=="lag" then
            object.text:SetText(format(MAINMENUBAR_LATENCY_LABEL:gsub("(.*)\n(.*)\n(.*)","%%s%1|r %2, %3"), tcolor, select(3, GetNetStats()),select(4, GetNetStats())))
        elseif i=="loot" then
            if UnitInParty("player") or UnitInRaid("player") then
                object.text:SetText(show_loot())
            end
        elseif i=="xp" then
            if UnitLevel("player") < 85 then
                object.text:SetText(format("%s XP: %s (%s)|r", tcolor, letter((UnitXPMax("player")-UnitXP("player")) + 1), letter(GetXPExhaustion() or 0))) 
                object.progress:SetValue((floor((UnitXP("player")/UnitXPMax("player"))*100)))
            else
                object.progress = nil
            end
        elseif i=="guild" then
            if IsInGuild() then
                object.text:SetText(format("%s "..ACHIEVEMENTS_GUILD_TAB.."|r", tcolor))
                if (object.bar:GetWidth() < (object.text:GetStringWidth()+10) or  object.bar:GetWidth() > (object.text:GetStringWidth()+20)) then
                    object.bar:SetWidth(object.text:GetStringWidth()+22)
                end
            end
        elseif i=="mem" then
            object.text:SetText(format(TOTAL_MEM_MB_ABBR:gsub("(.*):(.*)","%1").." %s", memoryval(collectgarbage("count"))))
        elseif i=="honor" then
            local _, camount, cicon = GetCurrencyInfo(CONQUEST_CURRENCY)
            local _, hamount, hicon = GetCurrencyInfo(HONOR_CURRENCY)
            
            object.text:SetText(format("%s"..HONOR_POINTS..":|r |TInterface/PVPFrame/%s:22:22:0:0:64:64:4:60:4:60|t%s|TInterface/PVPFrame/%s:22:22:0:0:64:64:4:60:4:60|t%s", tcolor, cicon, camount, hicon, hamount))
        elseif i=="zone" then
            object.text:SetText(format("%s"..ZONE..":|r %s", tcolor, GetMinimapZoneText()))
        end
        
        object.bar:SetWidth(object.text:GetWidth()+25)
    end
end

local openMicroMenu = function(self)
    if not _G["MicroMenuDropDown"] then
        local MicroMenuDropDown = CreateFrame('Frame', 'MicroMenuDropDown', UIParent, 'UIDropDownMenuTemplate')
        local calendar = SLASH_CALENDAR1:gsub("/(.*)","%1")
        UIDropDownMenu_Initialize(MicroMenuDropDown, function()
            local button = {
                { text = MAINMENU_BUTTON, func = function() ShowUIPanel(GameMenuFrame) end, notCheckable = 1 },
                { text = CHARACTER_BUTTON, func = function() ToggleCharacter('PaperDollFrame') end, notCheckable = 1 },
                { text = SPELLBOOK_ABILITIES_BUTTON, func = function() ToggleFrame(SpellBookFrame) end, notCheckable = 1 },
                { text = TALENTS_BUTTON, func = function() ToggleTalentFrame() end, notCheckable = 1 },
                { text = ACHIEVEMENT_BUTTON, func = function() ToggleAchievementFrame() end, notCheckable = 1 },
                { text = calendar, func = function() ToggleCalendar() end, notCheckable = 1 },
                { text = QUESTLOG_BUTTON, func = function() ToggleFrame(QuestLogFrame) end, notCheckable = 1 },
                { text = SOCIAL_BUTTON, func = function() ToggleFriendsFrame() end, notCheckable = 1 },
                { text = GUILD, func = function() ToggleGuildFrame() end, notCheckable = 1 },
                { text = PLAYER_V_PLAYER, func = function() ToggleFrame(PVPFrame) end, notCheckable = 1 },
                { text = LFG_TITLE, func = function() ToggleLFDParentFrame() end, notCheckable = 1 },
                { text = HELP_BUTTON, func = function() ToggleHelpFrame() end, notCheckable = 1 },
            }
            
            for i=1, 12 do
                 UIDropDownMenu_AddButton(button[i])
            end
        end, 'MENU')
    end
    ToggleDropDownMenu(1, nil, _G["MicroMenuDropDown"], self, -0, -0)
end

function show_addons(self)
   GameTooltip:SetOwner(self, "ANCHOR_BOTTOM")
   local total, addons, all_mem = 0, {}, collectgarbage("count")
    UpdateAddOnMemoryUsage()  
    for i=1, GetNumAddOns(), 1 do  
      if (GetAddOnMemoryUsage(i) > 0 ) then
        memory = GetAddOnMemoryUsage(i)  
        entry = {name=GetAddOnInfo(i), memory = memory}
        table.insert(addons, entry)  
        total = total + memory  
      end
    end  
    table.sort(addons, function(a, b) return a.memory > b.memory end)  
    line("ADDONS MEMORY USAGE :", "\n")  
    i = 0  
    for _, entry in pairs(addons) do  
        line(entry.name, memoryval(entry.memory)) 
        i = i + 1  
        if i >= 50 then  break  end  
    end  
    space()
    line("Addons", memoryval(total))
    line("Blizzard", memoryval(all_mem-total))
    line("Total", memoryval(all_mem))
    if not UnitAffectingCombat("player") then GameTooltip:Show() end
end

function cString(name, point, ...)
    if SCDB["Main"]["ClassColorTheme"] == false then
        color = { r=1, g=1, b=1, a=1 }
    end
    
    local lastobject = nil
    for i, object in pairs(objects) do
        if object.child == false then
            objects[i].child = true
            lastobject = objects[i]
            break
        end
    end

    local btn = CreateFrame("button", nil, Holder)
    
    btn:SetScript("OnEnter", Holder:GetScript("OnEnter"))
    btn:SetScript("OnLeave", Holder:GetScript("OnLeave"))
    
    if (lastobject) then
        btn:SetPoint("LEFT", lastobject.bar, "RIGHT", 0, 0)
    else
        btn:SetPoint("LEFT", Holder, "LEFT", 0, 0)
    end
    
    btn:SetWidth(UIParent:GetWidth()/table.getn(objects))
    btn:SetHeight(Holder:GetHeight())
    btn:EnableMouse(true)

    local zstr = createFs(btn)
    zstr:SetPoint("CENTER")
    zstr:SetJustifyV("MIDDLE")

    if type(point) == "string" then
        if point == "progress" then
            local val1, val2 = select(1, ...)
            btn.pb = CreateFrame("StatusBar", nil, btn)
            btn.pb:SetStatusBarTexture("Interface\\Addons\\"..addonName.."\\media\\texture\\statusbar")
            btn.pb:SetPoint("TOPLEFT", btn, "TOPLEFT", 0, 0)
            btn.pb:SetPoint("BOTTOMRIGHT", btn, "BOTTOMRIGHT", 0, 0)
            btn.pb:SetMinMaxValues(val1, val2)
            btn.pb:SetStatusBarColor(color.r, color.g, color.b)

            btn.pb.bg = btn.pb:CreateTexture(nil, "BACKGROUND")
            btn.pb.bg:SetTexture("Interface\\BUTTONS\\WHITE8X8")
            btn.pb.bg:SetDesaturated(1)
            btn.pb.bg:SetPoint("TOPLEFT", 0, 0)
            btn.pb.bg:SetPoint("BOTTOMRIGHT", 0, 0)
            btn.pb.bg:SetVertexColor(1,1,1,.2)
            
            zstr = createFs(btn.pb)
            zstr:SetPoint("CENTER")
            zstr:SetJustifyV("MIDDLE")
            
            objects[name] = { text = zstr, bar = btn, child = false , progress = btn.pb, }
        end
    elseif type(point) == "function" then
        btn:SetScript("OnClick", point)
        btn:SetScript("OnLeave", function() GameTooltip:Hide() end)
        objects[name] = { text = zstr, bar = btn, child = false , progress = nil, }
    else
        objects[name] = { text = zstr, bar = btn, child = false , progress = nil, }
    end

    return btn
end

function show_durability()
   local cost, ndx, durability, d_val, d_max = GetRepairAllCost(), 0, 0, 0, 0
   for slot = 0, 19 do
      d_val, d_max = GetInventoryItemDurability(slot)
      if(d_val) then durability = durability + d_val/d_max*100 ndx=ndx+1 
      end 
   end
   durability = floor(durability/ndx)
   local out_string = gradient_s(floor(durability), 0, 100)..floor(durability).."|r % "
   if(cost > 0) then return format("%s[%s]", out_string, cost) end
   return out_string, durability + 1
end

function show_guild(self, rt)
    if not _G["GuildListDropDown"] then
        local GuildListDropDown = CreateFrame('Frame', 'GuildListDropDown', UIParent, 'UIDropDownMenuTemplate')
        UIDropDownMenu_Initialize(GuildListDropDown, function(self)
            if IsInGuild() then
                local tonline = 0
                local total = GetNumGuildMembers(true) or 0
                if self~=nil then
                    local gtable = {}
                    for ndx = 0, total do
                        local name, rnk, irnk, lvl, class, zone, note, onote, online, status, engclass, achpoints, achrank, mobile = GetGuildRosterInfo(ndx)
                        if (online and name) then 
                            tinsert(gtable, {name=name, rnk=rnk, irnk=irnk, lvl=lvl, class=class, zone=zone, note=note, onote=onote, online=online, status=status, engclass=engclass, achpoints=achpoints, achrank=achrank, mobile=mobile })
                            tonline = tonline + online
                        end
                    end
                    table.sort(gtable, function(a, b) return a.engclass > b.engclass end)
                    for i = 1, #gtable do
                        local data = gtable[i]
                        local button = {}
                        button.text = string.format("|cffdddd00%s|r  %s|r  [ %s ] |cff00bb22%s|r", data.lvl < MAX_PLAYER_LEVEL_TABLE[3] and data.lvl or "", classcol(data.engclass)..data.name or "", data.zone or "", data.note)
                        button.func = function() ChatFrame_SendTell(data.name, data.name) end
                        button.notCheckable = 1
                        UIDropDownMenu_AddButton(button)
                    end
                end
            end
        end, 'MENU')
    end
    ToggleDropDownMenu(1, nil, _G["GuildListDropDown"], self, -0, -0)
end

function memoryval(val)
    if val > 1024 then 
        return format("%s mb", gradient_s(floor(val), 0, 100)..floor(val/1024).."|r")
    else 
        return format("%s kb", gradient_s(floor(val),0, 100)..floor(val)) 
    end
end


function show_loot()
    local lootmethod, masterlooterPartyID, masterlooterRaidID = GetLootMethod()
    local master = ""
    if masterlooterPartyID then 
        master = "("..UnitName("party"..masterlooterPartyID)..")" or ""
    elseif masterlooterRaidID then
        master = "("..UnitName("raid"..masterlooterRaidID)..")" or ""
    else
        master = ""
    end

    objects["loot"].bar:SetWidth(objects["loot"].text:GetStringWidth()+30)
    return format("%s%s %s|r", select(4,GetItemQualityColor(GetLootThreshold())), lootmethod, master)
end

function classcol(class)
   if not _G["RAID_CLASS_COLORS"] or class == nil then return ("|cffffffff") end
   local color = _G["RAID_CLASS_COLORS"][strupper(class)]
   return format("|cff%02x%02x%02x", color.r*255, color.g*255, color.b*255)
end

local module = {}
module.name = "Data text"
module.Init = function()
    if not SCDB.modules[module.name] then return end
    
    if SCDB[module.name] == nil then SCDB[module.name] = {} end
    
    if SCDB[module.name]["AutoHide"] == nil then SCDB[module.name]["AutoHide"] = false end
    if SCDB[module.name]["Gold"] == nil then SCDB[module.name]["Gold"] = true end
    if SCDB[module.name]["Durability"] == nil then SCDB[module.name]["Durability"] = true end
    if SCDB[module.name]["Latency"] == nil then SCDB[module.name]["Latency"] = true end
    if SCDB[module.name]["Guild information"] == nil then SCDB[module.name]["Guild information"] = true end
    if SCDB[module.name]["Show loot settings"] == nil then SCDB[module.name]["Show loot settings"] = true end
    if SCDB[module.name]["Experience bar"] == nil then SCDB[module.name]["Experience bar"] = false end
    if SCDB[module.name]["Addon memory usage"] == nil then SCDB[module.name]["Addon memory usage"] = true end
    if SCDB[module.name]["Honor"] == nil then SCDB[module.name]["Honor"] = true end
    if SCDB[module.name]["Zone text"] == nil then SCDB[module.name]["Zone text"] = true end

    local opts = SCDB[module.name]
    
    Holder:SetFrameStrata("BACKGROUND")
    Holder:SetHeight(22)
    Holder:SetPoint("TOPLEFT", UIParent, "TOPLEFT", 0, 0)
    Holder:SetPoint("BOTTOMRIGHT", UIParent, "TOPRIGHT", 0, -22)
        
    
    local set_anim = function (self, x, y)
        self.anim = self:CreateAnimationGroup("Move_In")
        self.anim_o = self:CreateAnimationGroup("Move_Out")

        self.anim.in_a = self.anim:CreateAnimation("Alpha")
        self.anim.in_a:SetDuration(.3)
        self.anim.in_a:SetSmoothing("OUT")
        self.anim.in_a:SetChange(1)
        
        self.anim_o.b = self.anim_o:CreateAnimation("Alpha")
        self.anim_o.b:SetDuration(.3)
        self.anim_o.b:SetSmoothing("IN")
        self.anim_o.b:SetChange(-1)
        
        self.anim:SetScript("OnFinished", function() 
            self:SetAlpha(1)
        end)
        self.anim_o:SetScript("OnFinished", function() 
            self:SetAlpha(0)
        end)
    end

    if SCDB[module.name]["AutoHide"] == true then
        Holder:SetAlpha(0)
        set_anim(Holder, 0, 14)

        Holder:SetScript("OnEnter",function(self)
            Holder.anim:Play()
            Holder.anim_o:Stop()
        end)

        Holder:SetScript("OnLeave",function(self)
            Holder.anim:Stop()
            Holder.anim_o:Play()
        end)
    end
    
    cString("Menu", openMicroMenu, "border")

    if opts["Gold"] then cString("gold") end
    if opts["Durability"] then cString("dura", "progress", 0, 100) end
    if opts["Latency"] then cString("lag") end
    if opts["Guild information"] then 
        cString("guild", show_guild, "border")
        --cString("guild", show_guild)
    end
    if opts["Show loot settings"] then cString("loot") end
    if opts["Experience bar"] then if UnitLevel("player") < 85 then cString("xp", "progress", 0, 100) end end
    if opts["Addon memory usage"] then cString("mem", show_addons) end
    if opts["Honor"] then cString("honor") end
    if opts["Zone text"] then cString("zone") end
    
    Holder:SetScript("OnUpdate", function(self, elapsed)
        if self.lt== nil then self.lt=0 end
        self.lt = self.lt + elapsed
        if self.lt > 1 then
            checkStats()
            self.lt=0
        end
    end)
    
    for i, object in pairs(objects) do
        object.bar:SetWidth(object.text:GetStringWidth()+30)
    end
    
    local eventframe = CreateFrame("Frame")
    eventframe:RegisterEvent("PLAYER_ENTERING_WORLD")
    eventframe:RegisterEvent("ZONE_CHANGED")
    eventframe:RegisterEvent("ZONE_CHANGED_INDOORS")
    eventframe:RegisterEvent("ZONE_CHANGED_NEW_AREA")
    eventframe:RegisterEvent("GUILD_ROSTER_UPDATE")
    eventframe:RegisterEvent("PLAYER_XP_UPDATE")
    eventframe:RegisterEvent("UNIT_LEVEL")
    eventframe:RegisterEvent("UPDATE_INVENTORY_DURABILITY")
    eventframe:RegisterEvent("PARTY_LOOT_METHOD_CHANGED")
    eventframe:RegisterEvent("HONOR_CURRENCY_UPDATE")
    eventframe:RegisterEvent("HONOR_GAIN")
    eventframe:RegisterEvent("WORLD_STATE_UI_TIMER_UPDATE")
    eventframe:RegisterEvent("PLAYER_MONEY")
    
    eventframe:SetScript("OnEvent", function(self, event)
        checkStats()
    end)
end
tinsert(SuperClassic.modules, module) -- finish him!